package com.whfc.emp.manager.impl;

import com.whfc.common.exception.BizException;
import com.whfc.common.face.wo.WoFaceApi;
import com.whfc.common.face.wotu.WotuApiAddDeviceResult;
import com.whfc.common.face.wotu.WotuApiAddFaceImgResult;
import com.whfc.common.face.wotu.WotuApiAddPersonResult;
import com.whfc.common.face.wotu.WotuApiResult;
import com.whfc.common.geometry.Point;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.third.map.MapApi;
import com.whfc.common.third.map.MapLoc;
import com.whfc.emp.dao.AppEmpMapper;
import com.whfc.emp.dao.AppFaceGateFaceMapper;
import com.whfc.emp.dao.AppFaceGateMapper;
import com.whfc.emp.dao.AppFaceGatePersonMapper;
import com.whfc.emp.entity.*;
import com.whfc.emp.enums.FaceGateType;
import com.whfc.emp.enums.TaskType;
import com.whfc.emp.manager.FaceGateManager;
import com.whfc.emp.param.*;
import com.whfc.emp.redis.FaceGateApiTokenRedisDao;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.regex.Pattern;

/**
 * @Description wo平台
 * @Author hw
 * @Date 2021/1/21 16:38
 * @Version 1.0
 */
@Service("woFaceGateManagerImpl")
public class WoFaceGateManagerImpl implements FaceGateManager {

    private static final Logger logger = LoggerFactory.getLogger(WotuFaceGateManagerImpl.class);

    @Autowired
    private AppEmpMapper appEmpMapper;

    @Autowired
    private AppFaceGateMapper appFaceGateMapper;

    @Autowired
    private AppFaceGatePersonMapper appFaceGatePersonMapper;

    @Autowired
    private AppFaceGateFaceMapper appFaceGateFaceMapper;

    @Autowired
    private FaceGateApiTokenRedisDao faceGateApiTokenRedisDao;

    @Autowired
    private MapApi mapApi;

    private String appId;

    private WoFaceApi woFaceApi;

    /***
     * 默认为本地识别
     */
    private final static String type = "1";

    /**
     * 成功标识
     */
    private final static String WO_SUS1000 = "WO_SUS1000";

    /**
     * 设备离线
     */
    private final static String WO_EXP_104 = "WO_EXP-104";

    /**
     * 设备已添加
     */
    private final static String WO_EXP_103 = "WO_EXP-103";

    /**
     * 人员不存在
     */
    private final static String WO_EXP_400 = "WO_EXP-400";

    private final static String NAME_PATTERN = "^[\\u4e00-\\u9fa5a-zA-Z\\d\\s_]*$";

    @Override
    public void info(AppFaceGateConfig appFaceGateConfig) {
        String appId = appFaceGateConfig.getAppId();
        String appKey = appFaceGateConfig.getAppKey();
        String appSecret = appFaceGateConfig.getAppSecret();
        woFaceApi = new WoFaceApi(appId, appKey, appSecret);
        this.appId = String.valueOf(appFaceGateConfig.getId());
    }

    @Override
    public void add(AppFaceGateAddParam request) throws BizException{
        String deviceKey = request.getDeviceKey();
        String name = request.getName();
        Integer deptId = request.getDeptId();
        Point point = request.getPoint();
        if (!Pattern.matches(NAME_PATTERN, name)) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "设备名称应由数字\\字符\\空格\\“_”\\中文字符组成");
        }
        AppFaceGate appFaceGate = appFaceGateMapper.selectByDeviceKey(deviceKey);
        if (appFaceGate != null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该闸机已存在，不能重复添加！");
        }

        WotuApiResult<WotuApiAddDeviceResult> result = woFaceApi.deviceCreate(deviceKey, name, deptId + "", type, getToken());
        if (WO_EXP_104.equals(result.getCode())) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "设备不在线");
        }
        if (WO_EXP_103.equals(result.getCode())) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "设备已存在");
        }

        WotuApiAddDeviceResult data = result.getData();
        if (data != null) {
            AppFaceGate record = new AppFaceGate();
            BeanUtils.copyProperties(data, record);
            record.setDeptId(deptId);
            record.setName(name);
            record.setId(null);
            record.setDirection(request.getDirection());
            record.setPlatform(FaceGateType.WO.getCode());
            // 增加闸机位置信息
            if (point != null) {
                Double lat = point.getLat();
                Double lng = point.getLng();
                MapLoc loc = mapApi.geocode(lng, lat);
                record.setLng(lng);
                record.setLat(lat);
                record.setAddress(loc.getAddress());
            }
            appFaceGateMapper.insertSelective(record);
        }
    }

    @Override
    public void del(Integer faceGateId) throws BizException{
        AppFaceGate faceGate = appFaceGateMapper.selectByPrimaryKey(faceGateId);
        if (faceGate == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该闸机不存在");
        }
        Integer count = appFaceGatePersonMapper.countByFaceGateId(faceGateId);
        if (count > 0) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该闸机下还有人员未销权，不能删除！");
        }
        String deviceKey = faceGate.getDeviceKey();
        WotuApiResult wotuApiResult = woFaceApi.deviceDel(deviceKey, getToken());
        if (WO_SUS1000.equals(wotuApiResult.getCode())) {
            //成功
            appFaceGateMapper.deleteLogicById(faceGateId);
        }else{
            // 删除失败
            throw new BizException(ResultEnum.FAILURE.getCode(), "闸机删除失败");
        }
    }

    @Override
    public String faceGateGrantEmdAdd(FaceGateGrantEmdAddParam request) {
        Integer empId = request.getEmpId();
        Integer personId = request.getPersonId();
        AppEmp appPerson = appEmpMapper.selectByPrimaryKey(empId);
        if (appPerson == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "人员不存在");
        }
        String name = appPerson.getEmpName();
        String phone = appPerson.getPhone();
        if (!Pattern.matches(NAME_PATTERN, name)) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "姓名应由数字\\字符\\空格\\“_”\\中文字符组成");
        }
        //人员注册
        String token = getToken();
        logger.info("获取token={}",token);
        WotuApiResult<WotuApiAddPersonResult> result = woFaceApi.personCreate(name, phone, token);
        if (WO_SUS1000.equals(result.getCode())) {
            //人员注册成功
            WotuApiAddPersonResult data = result.getData();
            String personGuid = data.getGuid();
            appPerson.setEmpCode(personGuid);
            appEmpMapper.updateByPrimaryKey(appPerson);

            appFaceGatePersonMapper.updateGrantInfo(personId, TaskType.EMP_ADD.getValue(), personGuid);
            return personGuid;
        } else {
            logger.info("人员注册失败,name:{},code:{},message:{}", name, result.getCode(), result.getMsg());
            appFaceGatePersonMapper.updateTaskType(personId, TaskType.EMP_ADD_ERROR.getValue(), "人员注册失败");
            return null;
        }
    }

    @Override
    public String faceGateGrantEmdImgAdd(FaceGateGrantEmdImgAddParam request) {
        Integer personId = request.getPersonId();
        String personGuid = request.getPersonGuid();
        String imgUrl = request.getImgUrl();
        String token = getToken();
        logger.info("token={}", token);
        //照片注册
        WotuApiResult<WotuApiAddFaceImgResult> faceResult = woFaceApi.faceImgCreate(personGuid, imgUrl, token);
        if (WO_SUS1000.equals(faceResult.getCode())) {
            //照片注册接口调用成功
            AppFaceGatePerson appFaceGatePerson = appFaceGatePersonMapper.selectByPrimaryKey(personId);
            WotuApiAddFaceImgResult face = faceResult.getData();
            AppFaceGateFace appFaceGateFace = new AppFaceGateFace();
            appFaceGateFace.setDeptId(appFaceGatePerson.getDeptId());
            appFaceGateFace.setDeviceKey(appFaceGatePerson.getDeviceKey());
            appFaceGateFace.setEmpId(appFaceGatePerson.getEmpId());
            appFaceGateFace.setFaceGateId(appFaceGatePerson.getFaceGateId());
            appFaceGateFace.setFaceGuid(face.getGuid());
            appFaceGateFace.setFaceUrl(face.getFaceUrl());
            appFaceGateFace.setPersonGuid(personGuid);
            appFaceGateFaceMapper.insertSelective(appFaceGateFace);

            appFaceGatePersonMapper.updateTaskType(personId, TaskType.EMP_IMG_ADD.getValue(), "照片注册成功");

            return personGuid;
        } else {
            appFaceGatePersonMapper.updateTaskType(personId, TaskType.EMP_IMG_ADD_ERROR.getValue(), "照片注册失败");
            return null;
        }
    }

    @Override
    public String faceGateGrantEmdAuth(FaceGateGrantEmdAuthParam request) {
        String deviceKey = request.getDeviceKey();
        String personGuid = request.getPersonGuid();
        Integer personId = request.getPersonId();
        WotuApiResult result = woFaceApi.setPeople(deviceKey, personGuid, type, getToken());
        if (WO_SUS1000.equals(result.getCode())) {
            appFaceGatePersonMapper.updateTaskType(personId, TaskType.EMP_AUTH.getValue(), "人员授权成功");
            return personGuid;
        } else {
            appFaceGatePersonMapper.updateTaskType(personId, TaskType.EMP_AUTH_ERROR.getValue(), "人员授权失败");
            return null;
        }
    }

    @Override
    public void faceGateBatchGrantEmpAuth(AppFaceGateGrantEmpParam request) {

    }

    @Override
    public void faceGateRevokeEmp(AppFaceGateGrantEmpParam request) throws BizException{
        Integer faceGateId = request.getFaceGateId();
        List<Integer> empIdList = request.getEmpIdList();

        AppFaceGate faceGate = appFaceGateMapper.selectByPrimaryKey(faceGateId);
        if (faceGate == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该闸机不存在");
        }
        String deviceKey = faceGate.getDeviceKey();
        for (Integer empId : empIdList) {
            List<String> personGuids = appFaceGatePersonMapper.selectPersonGuidByFaceGateIdAndEmpId(faceGateId, empId);
            if (personGuids != null && personGuids.size() > 0) {
                for (String personGuid : personGuids) {
                    if (StringUtils.isNotBlank(personGuid)) {
                        WotuApiResult wotuApiResult = woFaceApi.deleteSomePeople(deviceKey, personGuid, type, getToken());
                        woFaceApi.personDelete(personGuid,getToken());
                        if (WO_SUS1000.equals(wotuApiResult.getCode()) || WO_EXP_400.equals(wotuApiResult.getCode())) {
                            //成功 or 人员不存在
                            appFaceGatePersonMapper.delBYDeviceKeyAndParsonGuid(deviceKey, personGuids);
                        } else {
                            logger.warn("删除授权失败，personGuid：{},{}", personGuid, wotuApiResult.getCode());
                        }
                    } else {
                        appFaceGatePersonMapper.delByDeviceKeyAndEmpId(deviceKey, empId);
                    }
                }
            }
        }


    }

    @Override
    public String deviceAuthorizationPerson(String deviceKey, String name, String imgUrl) throws BizException{
        if (!Pattern.matches(NAME_PATTERN, name)) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "姓名应由数字\\字符\\空格\\“_”\\中文字符组成");
        }
        //人员注册
        WotuApiResult<WotuApiAddPersonResult> personResult = woFaceApi.personCreate(name, null, getToken());
        if (WO_SUS1000.equals(personResult.getCode())) {
            //人员注册成功
            WotuApiAddPersonResult data = personResult.getData();
            String personGuid = data.getGuid();
            WotuApiResult<WotuApiAddFaceImgResult> faceResult = woFaceApi.faceImgCreate(personGuid, imgUrl, getToken());
            if (WO_SUS1000.equals(faceResult.getCode())) {
                WotuApiResult result = woFaceApi.setPeople(deviceKey, personGuid, type, getToken());
                if (WO_SUS1000.equals(result.getCode())) {
                    return personGuid;
                }
            }
        }
        throw new BizException(ResultEnum.FAILURE.getCode(), "人员授权失败");
    }

    @Override
    public String deviceAuthorizationCancel(String deviceKey, String personGuid) {
        String result = "";
        WotuApiResult wotuApiResult = woFaceApi.deleteSomePeople(deviceKey, personGuid, type, getToken());
        if (wotuApiResult != null) {
            result = wotuApiResult.getCode();
        }
        return result;
    }

    @Override
    public void openDoor(String deviceKey) throws BizException{
        WotuApiResult wotuApiResult = woFaceApi.interactive(deviceKey, getToken());
        if (!WO_SUS1000.equals(wotuApiResult.getCode())) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "闸机开门失败");
        }
    }

    @Override
    public void sync(Integer faceGateId) {

    }

    @Override
    public String getToken() throws BizException{
        String accessToken = faceGateApiTokenRedisDao.getAccessToken(this.appId);
        if (StringUtils.isEmpty(accessToken)) {
            accessToken = woFaceApi.auth();
            if (StringUtils.isEmpty(accessToken)) {
                throw new BizException(ResultEnum.FAILURE.getCode(), "配置服务异常请联系管理员");
            }
            faceGateApiTokenRedisDao.setAccessToken(this.appId, accessToken);
        }
        return accessToken;
    }
}
